<script setup lang="ts">
import { defineProps, defineExpose, computed, inject, toRaw, reactive, watchEffect, watch } from 'vue'
import type { ComponentInternalInstance } from 'vue'
import { omit } from 'lodash-es'
import { ConditionType } from '/@/utils/dynamicCondition'
import dayjs from 'dayjs'

const tableRoot = inject<ComponentInternalInstance>('tableRoot')
const tableScopeEvents = inject<any>('tableScopeEvents')
const tableEmit = inject<any>('tableEmit')

const defaultParams = computed(() => toRaw(tableRoot.props.remoteConfig?.params))

const filterColumns = computed(() => toRaw(tableRoot.props.columns.filter(s => !!s.filter || !!s.filterComponent)) as YTableColumn[])


const props = defineProps({
  options: { type: Array as PropType<YTableFilter[]>, default: () => [], required: true }
})

const useElFormItems = (options: YTableFilter[]) => {
  return options.map(opt => ({
    field: opt.field,
    component: opt.component || 'ElInput',
    itemProps: {
      label: opt.label,
      prop: opt.field
    }
  }))
}

const showOptions = computed(() => useElFormItems(props.options.filter(s => !s.fold)))

const firstCol = filterColumns.value.find((_, i) => i === 0)

const model = reactive({ _filterField: firstCol?.field, _filterValue: null })

watch(() => model._filterField, () => {
  model._filterValue = null
})

watchEffect(() => {
  if (defaultParams.value) {
    Object.assign(model, defaultParams.value)
  }
})

const filterPlaceholder = computed(() => {
  if (!model._filterField) return '请输入'

  const column = filterColumns.value.find(s => s.field === model._filterField)
  return '请输入' + column?.label
})

const filterComponentRender = computed(() => {
  if (!model._filterField) return 'ElInput'
  const column = filterColumns.value.find(s => s.field === model._filterField)
  return column.filterComponent || 'ElInput'
})

const getConditionlType = (val: any, column: YTableColumn) => {
  const filterCompStr = typeof filterComponentRender.value === 'string' ? filterComponentRender.value : filterComponentRender?.key

  if (['ElDatePicker', 'ElDateTimePicker'].includes(filterCompStr)) {
    return ConditionType.Equal
  }
  else {
    return ConditionType.Like;
  }
}

const getReasonableVal = (val: any) => {
  const filterCompStr = typeof filterComponentRender.value === 'string' ? filterComponentRender.value : filterComponentRender?.key

  if (['ElDatePicker', 'ElDateTimePicker'].includes(filterCompStr)) {
    return dayjs(val).format('YYYY-MM-DD HH:mm:ss')
  } else {
    return val;
  }

}

tableScopeEvents.on('loadDataBefore', (params) => {
  const assignParams = {
    ...toRaw(model)
  }

  Object.assign(params, {
    ...omit(assignParams, [...Object.keys(assignParams).filter(k => k.startsWith('_'))])
  })

  const currFilterColumn = filterColumns.value.find(s => s.field === model._filterField)
  if (model._filterField && model._filterValue && currFilterColumn) {
    params['filters'] = params['filters'] || []

    const conditionalType = currFilterColumn.filterType ?? getConditionlType(model._filterValue, currFilterColumn)
    if (conditionalType !== void 0) {
      params['filters'].push({
        fieldName: model._filterField,
        fieldValue: getReasonableVal(model._filterValue),
        conditionalType: conditionalType,
      })
    }

  }
})

const handSearch = () => {
  tableScopeEvents.emit('loadData')
}

const handReset = () => {
  Object.keys(model).forEach(k => {
    model[k] = ''
  })
}

const handChange = () => {
  tableEmit('filter-change', model)
}

defineExpose({
  getData: () => toRaw(model)
})
</script>
<template>
  <el-form class="y-table-filters" :inline="true" :model="model">
    <template v-if="filterColumns.length">
      <el-form-item label="筛选" prop="_filterField">
        <div class="y-table-filters__common">
          <el-select v-model="model._filterField">
            <el-option v-for="col of filterColumns" :key="col.field" :value="col.field" :label="col.label" />
          </el-select>
          <component-render :render="filterComponentRender" v-model="model._filterValue"
            :placeholder="filterPlaceholder" :disabled="!model._filterField" @keydown.enter="handSearch"
            @change="handChange" />
        </div>
      </el-form-item>
    </template>

    <el-form-item v-for="(item, index) of showOptions" :key="index" v-bind="item.itemProps">
      <component-render :render="item.component" v-model="model[item.itemProps.prop as string]"
        :placeholder="'请输入' + item.itemProps.label" @keydown.enter="handSearch" @change="handChange" />
    </el-form-item>


    <el-form-item>
      <el-button type="primary" @click="handSearch">
        搜索
        <template #icon>
          <iconify-icon-offline icon="search" />
        </template>
      </el-button>
      <el-button @click="handReset">
        重置
        <template #icon>
          <iconify-icon-offline icon="refresh" />
        </template>

      </el-button>
    </el-form-item>
  </el-form>
</template>
